<?php

namespace App\Service\Kms\Album;

use App\Models\Kms\Album\AlbumResourceModel;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Kuafu\File\FileUtil;
use OSS\Core\OssException;

class AlbumResourceZipDownloader
{
    protected string $tmpDir      = '';
    protected array  $files       = [];
    protected string $zipFilePath = '';

    public function __construct()
    {
        $this->prepareTmpDir();
        if (!function_exists('proc_open')) {
            throw new \RuntimeException('proc_open disabled');
        }
    }


    public function __destruct()
    {
        if (is_dir($this->tmpDir)) {
            app(Filesystem::class)->deleteDirectory($this->tmpDir, true);
            @rmdir($this->tmpDir);
        }
    }

    protected function prepareTmpDir()
    {
        $this->tmpDir = sys_get_temp_dir() . '/kuafu/tiger_api/album_resource/fod_' . Str::random(8);
        if (is_dir($this->tmpDir)) {
            // 清空这个dir
            app(Filesystem::class)->deleteDirectory($this->tmpDir, true);
            @rmdir($this->tmpDir);
        }
        mkdir($this->tmpDir, 0777, true);
        $this->zipFilePath = dirname($this->tmpDir) . '/fod_' . Str::random(8) . '.7z';
    }

    protected function localFilePath(array $file): string
    {
        return $this->tmpDir . '/' . $file['addressPrefix'] . $file['addressSuffix'] . $file['resourceNo'] . $file['suffix'];
    }

    protected function files($ids)
    {
        $files = [];
        // 准备文件数据
        AlbumResourceModel::query()
            ->whereIn('id', $ids)
            ->where("type", AlbumResourceModel::TYPE_RESOURCE_1)
            ->where("isDeleted", 0)
            ->chunkById(
                100, function ($item) use (&$files) {
                foreach ($item as $v) {
                    if ($v->originalUrl) {
                        $suffixArr = explode('.', basename(urldecode($v->originalUrl)));
                        if (count($suffixArr) > 1) {
                            $suffix = '.' . explode('?', $suffixArr[count($suffixArr) - 1])[0];
                        } else {
                            $suffix = '';
                        }
                        $files[] = [
                            'type'          => $v->type,
                            'url'           => $v->originalUrl,
                            'suffix'        => $suffix,
                            'resourceNo'    => $v->resourceNo,
                            'addressPrefix' => $v->addressPrefix,
                            'addressSuffix' => $v->addressSuffix,
                        ];
                    }
                }
            }
            );
        if ($files) {

            // 下载图片文件
            foreach ($files as $file) {
                $localFilePath = $this->localFilePath($file);
                static::streamDownload($localFilePath, $file['url']);
            }
        }
    }

    protected function makeArchive($uid)
    {
        // 删掉空文件
        foreach (app(Filesystem::class)->files($this->tmpDir) as $v) {
            if ($v->getSize() < 1) {
                @unlink($v->getPathname());
            }
        }
        putenv('LC_ALL=en_US.UTF-8');
        $command = sprintf('7za a "%s" "%s"', $this->zipFilePath, rtrim($this->tmpDir, '/') . '/*');
        $r       = shell_exec($command);
        if (null === $r) {
            $r = 'null';
        }
        if (false === $r) {
            $r = 'false';
        }
        Log::info("相册批量文件下载：{$uid}，临时目录：{$this->tmpDir}，执行命令：[{$command}]，执行结果：" . $r);
    }


    protected static function streamDownload(string $localPath, string $url)
    {
        $fd = $local = null;
        @unlink($localPath);
        try {
            $basepath = base_path($localPath);
            if (!is_dir($basepath)) {
                mkdir($basepath, 0777, true);
            }
            $local = fopen($localPath, 'wb');
            $fd    = fopen($url, 'rb');
            while (!feof($fd)) {
                fwrite($local, fread($fd, 1024 * 1024), 1024 * 1024);
            }
        } catch (\Exception $e) {
            Log::error(
                '相册批量文件下载失败：', [
                    'localPath' => $localPath,
                    'url'       => $url,
                    'msg'       => $e->getMessage(),
                ]
            );
        }
        is_resource($fd) && fclose($fd);
        is_resource($local) && fclose($local);
    }

    /**
     * 生成文件下载response对象
     * @param $ids
     * @param $uid
     * @return array
     * @throws OssException
     */
    public function fileResponse(array $ids, int $uid): array
    {
        $this->files($ids);
        $this->makeArchive($uid);
        if (!is_file($this->zipFilePath)) {
            Log::info(
                'fileResponseNotFilePath:', [
                    'ids' => $ids,
                    'uid' => $uid,
                ]
            );
            return [];
        }
        // 上传文件到OSS临时目录
        $OssObjectName = 'tmp/albumResource/' . date('Ymd') . '/' . Str::random(8) . '/相册批量下载-' . time() . '.7z';
        $ossInfo       = FileUtil::uploadFile($this->zipFilePath, '.7z', $OssObjectName);
        @unlink($this->zipFilePath);
        return $ossInfo;
    }


}
